package com.stlm2.dems.shiro;

import com.stlm2.core.redis.RedisClient;
import com.stlm2.dataSource.DBContextHolder;
import com.stlm2.dems.entity.User;
import com.stlm2.dems.user.dao.RoleDao;
import com.stlm2.dems.user.dao.SystemPrivilegeDao;
import com.stlm2.dems.dao.UserDao;
import com.stlm2.dems.user.entity.*;
import com.stlm2.util.DataSourceURLUtil;
import com.stlm2.util.DataSourceUtil;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;


import javax.annotation.Resource;
import java.util.*;

public class ShiroRealm extends AuthorizingRealm {
    @Resource
    private UserDao userDao;
    @Resource
    private SystemPrivilegeDao systemPrivilegeDao;
    @Resource
    private RoleDao roleDao;

/*
*
*授权
* ZLQ
*基于资源进行授权
 */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        // 当前登录的用户名
        Login login = (Login) super.getAvailablePrincipal(principalCollection);
        JedisPool pool = null;
        Jedis jedis = null;
        DataSourceURLUtil.changeDataSource(login.getHost());

        User user;
        try {
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            pool = RedisClient.getPool();
            jedis = pool.getResource();
            Set<String> userRoles = new HashSet<String>();
            Set<String> userPrivilege= new HashSet<String>();
            //从Redis中获取数据角色数据
            Set<String> redisUserRolesRecordList=jedis.keys(login.getHost() + login.getName() + "userRoles*");
            if(redisUserRolesRecordList!=null&&redisUserRolesRecordList.size()>0){
                for (String redisUserRolesRecord:redisUserRolesRecordList) {
                    String redisString[]=redisUserRolesRecord.split("#");
                    String redisUserRoles=redisString[1];
                    userRoles.add(redisUserRoles);
                }
            }
            //从Redis中获取数据资源数据
            Set<String> redisUserPrivilegeRecordList=jedis.keys(login.getHost() + login.getName() + "userPrivilege*");
            if(redisUserPrivilegeRecordList!=null&& redisUserPrivilegeRecordList.size()>0){
                for (String redisUserPrivilegeRecord:redisUserPrivilegeRecordList) {
                    String redisString[]=redisUserPrivilegeRecord.split("#");
                    String redisUserPrivilege=redisString[1];
                    userPrivilege.add(redisUserPrivilege);
                }
                //给角色授权
                info.setRoles(userRoles);
                //给资源授权
                info.setStringPermissions(userPrivilege);
                return info;
            }
            //Redis中没有数据,就从数据库中查找数据
            user = userDao.getByName(login.getName());
            if (user != null && !UserState.Invalid.equals(user.getUserState())) {
                Map map=new HashMap();
                //查找用户有什么样的角色
                 List<Role> roleList=roleDao.getByUserId(user.getId());
                if(roleList.size()>0){
                    for(Role role: roleList){
                        userRoles.add(role.getLabel());
                        jedis.incrBy(login.getHost() + login.getName() +  "userRoles#"+ role.getLabel(),1);
                        jedis.expire(login.getHost() + login.getName()  + "userRoles#" + role.getLabel(),60*60*1);//有效期1小时
                        //查找角色有什么样的资源
                       List<SystemPrivilege> systemPrivilegeList=systemPrivilegeDao.getByRoleId(role.getId());
                        if(systemPrivilegeList.size()>0){
                            //循环获取每个角色的资源
                            for(SystemPrivilege systemPrivilege : systemPrivilegeList){
                                userPrivilege.add(systemPrivilege.getPermissionName());
                                jedis.incrBy(login.getHost() + login.getName() + "userPrivilege#"+ systemPrivilege.getPermissionName(),1);
                                jedis.expire(login.getHost() + login.getName() + "userPrivilege#" + systemPrivilege.getPermissionName(),60*60*1);//有效期1小时
                            }
                        }
                    }
                }
                //查找用户有什么样的资源
                List<SystemPrivilege> systemPrivilegeList=systemPrivilegeDao.getByUserId(user.getId());
                if(systemPrivilegeList.size()>0){
                    //循环获取用户的资源
                    for(SystemPrivilege systemPrivilege : systemPrivilegeList){
                        userPrivilege.add(systemPrivilege.getPermissionName());
                        jedis.incrBy(login.getHost() + login.getName()  + "userPrivilege#"+ systemPrivilege.getPermissionName(),1);
                        jedis.expire(login.getHost() + login.getName() + "userPrivilege#" + systemPrivilege.getPermissionName(),60*60*1);//有效期1小时
                    }
                }
                //给角色授权
                info.setRoles(userRoles);
                //给资源授权
                info.setStringPermissions(userPrivilege);
                return info;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }finally {
            pool.returnResource(jedis);
            DBContextHolder.clearDBType();
        }

        return null;
    }
    /*
登录认证
ZLQ
 */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        User user =userDao.getByName(token.getUsername());
        SimpleAuthenticationInfo simpleAuthenticationInfo =new  SimpleAuthenticationInfo(Login.from(user,token.getHost()),
                user.getPassword(), getName());
        return simpleAuthenticationInfo;
    }
}
